package com.dkm.orproject.dkmoa.service.serviceimpl.flow;

import com.dkm.orproject.dkmoa.dao.*;
import com.dkm.orproject.dkmoa.domain.*;
import com.dkm.orproject.dkmoa.service.flow.OaEntryFlowService;
import com.dkm.orproject.utils.utils.IdToobtainUtils;
import com.dkm.orproject.utils.utils.Tools;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName : OaEntryFlowServiceImpl  //类名
 * @Description : 人事流程服务实现类  //描述
 * @Author : 易嵘  //作者
 * @Date: 2020-08-04 16:26  //时间
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class OaEntryFlowServiceImpl implements OaEntryFlowService {

    /**
     * 人事流程Mapper
     */
    @Resource
    OaEntryFlowMapper entryFlowMapper;

    /**
     * 流程记录日志
     */
    @Resource
    OaFlowScheduleMapper flowScheduleMapper;

    /**
     * 教育经历Mapper
     */
    @Resource
    OaEntryEducationMapper entryEducationMapper;

    /**
     * 家庭成员Mapper
     */
    @Resource
    OaEntryFamilyMapper entryFamilyMapper;

    /**
     * 培训经历Mapper
     */
    @Resource
    OaEntryTrainMapper entryTrainMapper;

    /**
     * 工作经历Mapper
     */
    @Resource
    OaEntryWorkMapper entryWorkMapper;

    /**
     * 紧急联系人Mapper
     */
    @Resource
    OaEmergencyContactMapper emergencyContactMapper;

    /**
     * 人员Mapper
     */
    @Resource
    OaPersonnelMapper personnelMapper;

    /**
     * 流程Mapper
     */
    @Resource
    OaFlowMapper flowMapper;

    /**
     * 通知Mapper
     */
    @Resource
    OaMessageMapper messageMapper;

    /**
     * 通知人员关联Mapper
     */
    @Resource
    OaInformMapper informMapper;


    /**
     * id生成工具
     */
    @Resource
    IdToobtainUtils idToobtainUtils;

    /**
     * 开始节点id
     */
    static final Long START_NODE = 751468029937856512L;

    /**
     * 审核节点id
     */
    static final Long AUDIT_NODE = 751468141183381504L;

    /**
     * 结束节点id
     */
    static final Long OVER_NODE = 751468190978158592L;

    static final String ENTRY_CHECK_INFORM="ENTRY_CHECK_INFORM";

    /**
     * 分页查询 权限查询未加入
     *
     * @param entryFlow 入职流程模型 用于条件查询
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param page      当前页数
     * @param limit     显示的行数
     * @param personnelId
     * @return 查询结果集
     */
    @Override
    public List<OaEntryFlow> findAll(OaEntryFlow entryFlow, String startTime, String endTime, Integer page, Integer limit, Long personnelId) {
        PageHelper.startPage(page, limit);
        return entryFlowMapper.findAll(entryFlow, startTime, endTime,personnelId);
    }

    /**
     * 总行数
     *
     * @param entryFlow 入职流程模型 用于条件查询
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param personnelId
     * @return 总行数
     */
    @Override
    public Long rowCount(OaEntryFlow entryFlow, String startTime, String endTime, Long personnelId) {
        return entryFlowMapper.rowCount(entryFlow, startTime, endTime,personnelId);
    }

    /**
     * 新增
     *
     * @param entryFlow 入职流程模型 用于新增
     * @param personnel 登陆人信息
     * @return 回调函数
     */
    @Override
    public int add(OaEntryFlow entryFlow, OaPersonnel personnel) {
        /*entryFlow.setPkEntryId(idToobtainUtils.getNumberId());*/
        entryFlow.setCreatedBy(personnel.getPkPersonnelId());
        entryFlow.setIsRevision("1");
        return entryFlowMapper.insertSelective(entryFlow);
    }

    /**
     * 起草提交
     *
     * @param entryFlow 入职流程模型 用于审核
     * @param personnel 登陆人信息
     * @return 回调函数
     */
    @Override
    public int audit(OaEntryFlow entryFlow, OaPersonnel personnel) {
        //名称赋值
        entryFlow.setEntryName(entryFlow.getEntryArea() + "的入职流程");
        //修改为待审关键字
        entryFlow.setIsRevision("S");
        //绑定审核流程
        entryFlow.setEntrySchedule(AUDIT_NODE);
        //更新人
        entryFlow.setUpdatedBy(personnel.getPersonnelName());
        //更新时间
        entryFlow.setUpdatedTime(new Date());
        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 入职流程id （起草流程）
        flowSchedule.setFlowId(START_NODE);
        // 流程进度
        flowSchedule.setFormId(entryFlow.getPkEntryId());
        //流程原因
        flowSchedule.setFormReason("起草流程");
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        // 操作人名称
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增入职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //删除旧通知
        messageMapper.deleteByFormId(entryFlow.getPkEntryId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(entryFlow.getPkEntryId());
        // 通知标题
        message.setMessageName(entryFlow.getEntryName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/entryAudit.html?pkEntryId=");
        // 新增通知
        messageMapper.insertSelective(message);
        // 根据流程id查询人员
        List<Long> personnelIds = personnelMapper.selectByHover(ENTRY_CHECK_INFORM);
        if (personnelIds.size() > 0) {
            // 通知人员关联集合
            List<OaInform> informs = new ArrayList<>();
            // 循环加入通知关联
            for (Long personnelId : personnelIds) {
                // 新建通知关联
                OaInform inform = new OaInform();
                // 通知关联id
                inform.setFkInformId(idToobtainUtils.getNumberId());
                // 设置为未读
                inform.setIsState("0");
                // 通知id
                inform.setMessageId(message.getPkMessageId());
                // 人员id
                inform.setPersonnelId(personnelId);
                // 加入通知关联
                informs.add(inform);
            }
            // 新增通知关联集合
            informMapper.insertAll(informs);
        }


        // 起草修改为待审
        return entryFlowMapper.updateByPrimaryKeySelective(entryFlow);
    }

    /**
     * 审核通过
     *
     * @param entryFlow  入职流程模型
     * @param formReason 审核原因
     * @param personnel  操作人
     * @return 回调函数
     */
    @Override
    public int auditPass(OaEntryFlow entryFlow, String formReason, OaPersonnel personnel) {
        BigDecimal trialMoney = entryFlow.getTrialMoney();
        BigDecimal officialMoney = entryFlow.getOfficialMoney();
        String trialDate = entryFlow.getTrialDate();

        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 入职流程id  审核节点
        flowSchedule.setFlowId(AUDIT_NODE);
        // 流程进度
        flowSchedule.setFormId(entryFlow.getPkEntryId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        //通过原因
        flowSchedule.setFormReason(formReason);
        // 操作人名称
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增入职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);

        //流程记录
        OaFlowSchedule flowSchedules = new OaFlowSchedule();
        flowSchedules.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 入职流程id 结束节点
        flowSchedules.setFlowId(OVER_NODE);
        // 流程进度
        flowSchedules.setFormId(entryFlow.getPkEntryId());
        // 人员id
        flowSchedules.setPersonnelId(personnel.getPkPersonnelId());
        //通过原因
        flowSchedules.setFormReason(" ");
        // 操作人名称
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增入职流程记录
        flowScheduleMapper.insertSelective(flowSchedules);
        entryFlow = entryFlowMapper.selectByPrimaryKey(entryFlow.getPkEntryId());
        // 试用期工资
        entryFlow.setTrialMoney(trialMoney);
        // 试用时间
        entryFlow.setTrialDate(trialDate);
        // 转正工资
        entryFlow.setOfficialMoney(officialMoney);
        //通知起草人审核完成
        //删除旧通知
        messageMapper.deleteByFormId(entryFlow.getPkEntryId());

        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(entryFlow.getPkEntryId());
        // 通知标题
        message.setMessageName(entryFlow.getEntryName());
        //状态 4 已办
        message.setIsRevision("4");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/entryAudit.html?show=1&pkEntryId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(personnel.getPkPersonnelId());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(entryFlow.getCreatedBy());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);

        //审核通过关键字
        entryFlow.setIsRevision("1");
        //赋值对应流程id 待优化
        entryFlow.setEntrySchedule(OVER_NODE);

        //创建一个新的人员
        OaPersonnel personnel1 = new OaPersonnel();
        // 人员id
        personnel1.setPkPersonnelId(idToobtainUtils.getNumberId());
        // 密码
        personnel1.setPersonnelPwd(Tools.password("123456"));
        // 有效性
        personnel1.setIsRevision("1");
        //绑定新增人员id
        entryFlow.setPersonnelId(personnel1.getPkPersonnelId());
        //结束流程
        entryFlowMapper.updateByPrimaryKeySelective(entryFlow);
        // 人员名称
        personnel1.setPersonnelName(entryFlow.getEntryArea());
        // 部门id
        personnel1.setOrganizationId(entryFlow.getDepartmentId());
        // 岗位id
        personnel1.setOrganizationType(entryFlow.getPostId());
        // 登录账号
        personnel1.setPersonnelAccount(entryFlow.getEntryArea());
        // 人员电话
        personnel1.setPersonnelPhone(entryFlow.getEntryPhone());
        //创建人
        personnel1.setCreatedBy(personnel.getPersonnelName());
        // 性别
        personnel1.setPersonnelSex(entryFlow.getEntrySex());
        // 新增人员
        return personnelMapper.insertSelective(personnel1);
    }

    /**
     * 审核不通过
     *
     * @param entryFlow  入职流程模型
     * @param formReason 审核原因
     * @param personnel  操作人
     * @return 回调函数
     */
    @Override
    public int auditNoPass(OaEntryFlow entryFlow, String formReason, OaPersonnel personnel) {
        //流程记录
        OaFlowSchedule flowSchedule = new OaFlowSchedule();
        flowSchedule.setPkFlowScheduleId(idToobtainUtils.getNumberId());
        // 入职流程id 审核节点
        flowSchedule.setFlowId(AUDIT_NODE);
        // 流程进度
        flowSchedule.setFormId(entryFlow.getPkEntryId());
        // 人员id
        flowSchedule.setPersonnelId(personnel.getPkPersonnelId());
        //通过原因
        flowSchedule.setFormReason(formReason);
        // 操作人名称
        flowSchedule.setCreatedBy(personnel.getPersonnelName());
        // 新增入职流程记录
        flowScheduleMapper.insertSelective(flowSchedule);
        //驳回至起草节点
        entryFlow.setIsRevision("C");
        // 赋值对应流程id 待优化
        entryFlow.setEntrySchedule(START_NODE);

        //删除旧通知
        messageMapper.deleteByFormId(entryFlow.getPkEntryId());
        // 新建通知
        OaMessage message = new OaMessage();
        //通知id
        message.setPkMessageId(idToobtainUtils.getNumberId());
        //创建人
        message.setCreatedBy(personnel.getPersonnelName());
        //流程id
        message.setFormId(entryFlow.getPkEntryId());
        // 通知标题
        message.setMessageName(entryFlow.getEntryName());
        //状态 2 待办
        message.setIsRevision("2");
        // 链接地址
        message.setMessageUrl("pages/dkmoa/front/flow/entryFrom.html?pkEntryId=");
        // 新增通知
        messageMapper.insertSelective(message);

        //关联通知
        OaInform inform = new OaInform();
        // 关联id
        inform.setFkInformId(idToobtainUtils.getNumberId());
        // 人员id
        inform.setPersonnelId(entryFlow.getCreatedBy());
        // 通知id
        inform.setMessageId(message.getPkMessageId());
        // 设置为 0 未读
        inform.setIsState("0");
        //新增通知关联
        informMapper.insertSelective(inform);

        return entryFlowMapper.updateByPrimaryKeySelective(entryFlow);
    }

    @Override
    public Long getThisRecord(Long pkPersonnelId) {
        return entryFlowMapper.getThisRecord(pkPersonnelId);
    }

    /**
     * 根据人员id查询自己的入职流程
     * @param personnelId 人员id
     * @return
     */
    @Override
    public OaEntryFlow findByPersonnelId(Long personnelId) {
        return entryFlowMapper.findByPersonnelId(personnelId);
    }

    /**
     * 删除（逻辑）
     *
     * @param list 入职流程id集
     * @return 回调函数
     */
    @Override
    public int deleteAll(List<Long> list) {
        return entryFlowMapper.deleteAll(list);
    }

    /**
     * 根据id集查询
     *
     * @param list 入职流程id集
     * @return 入职流程集
     */
    @Override
    public List<OaEntryFlow> selectAll(List<Long> list) {
        return entryFlowMapper.selectAll(list);
    }

    /**
     * id查询
     *
     * @param id 入职流程id
     * @return 入职流程
     */
    @Override
    public OaEntryFlow findById(Long id) {
        return entryFlowMapper.selectByPrimaryKey(id);
    }

    /**
     * id删除(物理)
     *
     * @param id 入职流程id
     * @return 回调函数
     */
    @Override
    public int deleteById(Long id) {
        //流程记录删除
        flowScheduleMapper.deleteByPrimaryKey(id);
        //教育经历删除
        entryEducationMapper.deleteByEntryFlowId(id);
        //家庭成员删除
        entryFamilyMapper.deleteByEntryFlowId(id);
        //培训经历删除
        entryTrainMapper.deleteByEntryFlowId(id);
        //工作经历删除
        entryWorkMapper.deleteByEntryFlowId(id);
        //紧急联系人删除
        emergencyContactMapper.deleteByEntryFlowId(id);
        return entryFlowMapper.deleteByPrimaryKey(id);
    }

    /**
     * 新增一个空的入职流程
     *
     * @param request 服务器请求
     * @return 回调函数
     */
    @Override
    public OaEntryFlow addEntryFlow(HttpServletRequest request) {
        //获取当前登陆人
        OaPersonnel personnel = (OaPersonnel) request.getSession().getAttribute("user");
        //查询是否有临时数据
        OaEntryFlow entryFlow = entryFlowMapper.selectCreatedBy(personnel.getPkPersonnelId());
        //为空时新建一个临时数据
        if (entryFlow == null || entryFlow.getPkEntryId() < 1) {
            OaEntryFlow entryFlows = new OaEntryFlow();
            entryFlows.setPkEntryId(idToobtainUtils.getNumberId());
            // 设置为临时数据 L为临时数据
            entryFlows.setIsRevision("L");
            entryFlows.setEntrySchedule(749961012475736064L);
            entryFlows.setCreatedBy(personnel.getPkPersonnelId());
            int row = entryFlowMapper.insertSelective(entryFlows);
            if (row > 0) {
                return entryFlows;
            } else {
                return null;
            }
        } else {
            //返回id
            return entryFlow;
        }
    }

    /**
     * 暂存临时数据
     *
     * @param entryFlow 入职流程模型
     * @param personnel 操作人
     * @return 回调函数 1成功 0失败
     */
    @Override
    public int addTemporary(OaEntryFlow entryFlow, OaPersonnel personnel) {
        entryFlow.setUpdatedBy(personnel.getPersonnelName());
        entryFlow.setUpdatedTime(new Date());
        return entryFlowMapper.updateByPrimaryKeySelective(entryFlow);
    }
}
